#Requires AutoHotkey v2.0

; 声明一个对象，并初始化其属性
myObject := {
    configFile: A_ScriptDir "\batData.properties", ; 配置文件路径
    dataFile: A_ScriptDir "\data.txt",             ; 数据文件路径
    texts: [],                                     ; texts 初始化为空数组
    defText: "#无数据#",			   ; 数据文件为空时粘贴的默认文本
    index: 1,                                      ; 初始索引为 1（AutoHotkey 数组从 1 开始）
    dataFileSize: 0                                ; 上次检测的文件大小
}

; 绑定 Ctrl+V 快捷键来发送 texts 数组中的字符串
^v:: {

    ; 检查 texts 数组是否为空,为空则从数据文件中读取数据
    if (myObject.texts.Length = 0){

	; 读取文件内容并将其存储在 texts 数组中
        readFile(myObject.dataFile)

	; 没有读到数据
	if (myObject.texts.Length = 0){
	    myObject.texts.Push(myObject.defText)
	    ; MsgBox myObject.defText
	}
    }
    
    ; 检查 数据文件是否发生改变，如果发生改变，重启脚本
    FileChanged := CheckFileChange(myObject.dataFile, myObject.dataFileSize)
    if(FileChanged != 0){
        Reload ; 重启脚本
    }
    
    ; 发送当前索引对应的文本
    ; Send(myObject.texts[myObject.index])

    Send(EscapeSpecialChars(myObject.texts[myObject.index]))
        
    ; 将索引递增
    myObject.index++
        
    ; 如果索引超出数组长度，重新设置为 1
    if (myObject.index > myObject.texts.Length) {
        myObject.index := 1
    }
    
}

; 绑定 Ctrl+Alt+Q 快捷键来退出脚本
^!q::ExitApp


; ----- 函数 -----


; 读取文件内容的函数
readFile(filePath) {
    global myObject
    fileContent := FileRead(filePath)  ; 使用函数风格读取文件内容
    lines := StrSplit(fileContent, "`n") ; 按行分割文件内容
    
    ; texts 初始化为空数组
    myObject.texts :=[]

    ; 去除每行的换行符并检查空行
    for index, line in lines {
    	trimmedLine := Trim(line, "`r`n")
        if (trimmedLine != "") {
            myObject.texts.Push(trimmedLine)
        }
    }
    myObject.dataFileSize := GetFileSize(myObject.dataFile)
}

; 用于转义特殊字符的函数
EscapeSpecialChars(str) {
    ; 定义需要转义的特殊字符及其替换值
    specialChars := ["#", "!", "^", "+","[", "]"]
    replacements := ["{#}", "{!}", "{^}", "{+}", "{[}", "{]}"]

    ; 循环遍历特殊字符数组，进行替换
    Loop specialChars.Length {
        str := StrReplace(str, specialChars[A_Index], replacements[A_Index])
    }
    Return str
}

; 检查文件大小变化的函数
CheckFileChange(fileToCheck, lastSize) {
    ; 获取当前文件大小
    fileSize := FileGetSize(fileToCheck)

    ; 检查文件大小是否变化
    if (fileSize != lastSize) {
        lastSize := fileSize
	; 文件大小未发生变化返回1
        return 1
    }

    ; 文件大小未发生变化返回0
    return 0
}


; 获取文件大小的辅助函数
GetFileSize(fileToCheck) {
    file := FileOpen(fileToCheck, "r")
    if !file
        return -1  ; 返回 -1 表示文件打开失败

    fileSize := file.Length
    file.Close()
    return fileSize
}


